2D/3D Visualizations & Interactive Plots#

Plot 2D/3D Data#

Values on a 2D grid (e.g. heights, images…) can be displayed using, for example, .imshow():

import numpy as np
from matplotlib import pyplot as plt
arr = np.random.random((20, 20)) * np.linspace(-1, 1, 20)

fig, ax = plt.subplots(figsize=(6, 6))
ax.imshow(arr)
plt.show()
../_images/d1cfb8ad7d27fec8e37ca84aec71f7713997a02587953c89bcc5faa541b08310.png

.contour()#

If you are less concerned with individual “pixels” or boxes and more with areas and boundaries or transitions, a contour plot is often also suitable:

fig, ax = plt.subplots(figsize=(6, 6))
ax.contour(arr)
plt.show()
../_images/c524347feae89701c7a5a685fbc3c06f1cab4f412f958f43b436bb27e1f30c2f.png

Here is another example of these two plot types with 3D data that we can display in 2D using imshow() or contour():

n = 500
x, y = np.meshgrid(np.linspace(-3, 3, n),
                   np.linspace(-3, 3, n))

z = (1 - x/2 + x**5 + y**3) * np.exp(-x**2 - y**2)
print(f"'z' has the shape: {z.shape}")
'z' has the shape: (500, 500)
z
array([[-4.07401958e-06, -4.29919749e-06, -4.53533585e-06, ...,
         3.62098001e-06,  3.44811482e-06,  3.28206063e-06],
       [-4.37287339e-06, -4.61446687e-06, -4.86781133e-06, ...,
         3.89741457e-06,  3.71122130e-06,  3.53237524e-06],
       [-4.69233163e-06, -4.95146515e-06, -5.22319372e-06, ...,
         4.19367707e-06,  3.99319078e-06,  3.80062746e-06],
       ...,
       [-3.76545993e-06, -3.95539782e-06, -4.15307442e-06, ...,
         5.26379637e-06,  4.98925812e-06,  4.72749916e-06],
       [-3.49964129e-06, -3.67604360e-06, -3.85962160e-06, ...,
         4.90560429e-06,  4.64964457e-06,  4.40560734e-06],
       [-3.25160068e-06, -3.41538087e-06, -3.58581248e-06, ...,
         4.57050338e-06,  4.33193144e-06,  4.10447954e-06]],
      shape=(500, 500))
fig, ax = plt.subplots(figsize=(6, 6))
ax.imshow(z)
<matplotlib.image.AxesImage at 0x7f61c85ad520>
../_images/8f3f44d28b147e87fcc226029a13e1ab898ec72caad79597f9a434b911114495.png

.contour()#

fig, ax = plt.subplots(figsize=(7, 7))
cs = ax.contour(z)
ax.clabel(cs, inline=True, fontsize=10)

plt.show()
../_images/cfe6c0b50012c2f732fb4de76178fbbf490241ade0770ab97f10bbbd0320da1a.png

3D is also possible (to a limited extent…)#

There are a few ways to create 3D visualizations with Matplotlib. However, this is quite limited. On the one hand, there are other tools and libraries that can display 3D data much better, i.e. faster, more beautifully and with less coding effort. On the other hand, most 3D representations are more suitable for interactive implementations, and this is also much better with other tools, in Python, for example, with Plotly, Vispy, and many others.

fig, ax = plt.subplots(subplot_kw={"projection": "3d"},
                      figsize=(8, 8), dpi=150)

surf = ax.plot_surface(x, y, z, cmap="viridis",
                       linewidth=0, antialiased=True)

ax.view_init(20, -50) # viewing angle
ax._axis3don = False # do not show axis
plt.show()
../_images/149ce2a9195654a05384720746b20770db6c3c7bf1775616260d6eb417ad3829.png

At the latest here, with 3D visualizations, we almost can’t avoid interactivity in practice.

Dynamic vs. static#

visualizations in Python can be divided into two main categories:

  • Static visualizations: These are created with libraries such as Matplotlib, Pandas or Seaborn. They are ideal for presentations and reports because they do not contain any interactive elements.

  • Dynamic visualizations: Libraries such as Plotly, Bokeh or Altair enable the creation of interactive plots in which users can, for example, zoom in, display details or update the display in real time. These are particularly suitable for dashboards and web-based applications.

import plotly.express as px

data = px.data.iris()
data.head()
---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
Cell In[9], line 1
----> 1 import plotly.express as px
      3 data = px.data.iris()
      4 data.head()

ModuleNotFoundError: No module named 'plotly'

Interactive Visualizations with Bokeh#

Bokeh is a powerful library that allows us to create interactive plots. This makes it possible to create visualizations that run directly in the web browser and support features such as zooming, panning, and displaying details.

Example: Scatterplot with Interactive Features#

from bokeh.plotting import figure, show
from bokeh.io import output_notebook

output_notebook()

colormap = {'setosa': 'red', 'versicolor': 'green', 'virginica': 'blue'}
colors = [colormap[x] for x in data['species']]

p = figure(title="Interaktiver Scatterplot (Iris Dataset)",
           x_axis_label="sepal_width",
           y_axis_label="sepal_length",
           tools="pan, box_zoom, reset, save")

# Punkte hinzufügen
p.scatter(data["sepal_width"], data["sepal_length"], fill_color=colors,
         size=10, fill_alpha=0.5)

# Plot anzeigen
show(p)
Loading BokehJS ...

Interactive visualizations with Altair#

Altair is based on the “Grammar of Graphics” and is ideal for quick and interactive visualizations. It offers intuitive syntax and is particularly popular for statistical visualizations.

Example: Scatterplot with tooltips#

import altair as alt


# Scatterplot erstellen
chart = alt.Chart(data).mark_circle(size=60).encode(
    x="sepal_width",
    y="sepal_length",
    color="species",
    size='sepal_length',
    tooltip=["sepal_width", "sepal_length", 'species']
).interactive()

chart

Interactive visualizations with Plotly Express#

Plotly is a versatile library that supports interactive visualizations. It is particularly suitable for dashboards and 3D visualizations. An even easier-to-use interface of Plotly is Plotly Express.

Example: 2D scatterplot#

import plotly.io as pio
import plotly.express as px
import plotly.offline as py

fig = px.scatter(
    data,
    x="sepal_width", y="sepal_length", color="species", size="sepal_length",
    width=800, height=800
    )
fig

Example: 3D Scatterplot#

fig = px.scatter_3d(
    data,
    x="sepal_width", y="sepal_length", z='petal_width',
    color="petal_length",
    symbol='species',
    width=800, height=800
    )
fig.show()

Plotly Express provides some very important standard plots. However, for visualizations that go beyond these, or require further special adjustments, it is sometimes necessary to access Ploty directly. For example, to render areas in 3D.

import plotly.graph_objects as go

# Read data from a csv
z_data = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/api_docs/mt_bruno_elevation.csv')

# Create the figure
fig = go.Figure(data=[go.Surface(z=z_data.values, colorscale='Viridis', showscale=False)])

# Update layout
fig.update_layout(
    title='Mt Bruno Elevation',
    autosize=False,
    width=800,
    height=800,
    margin=dict(l=65, r=50, b=65, t=90)
)

fig.show()